﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using Road3App.Model.CrossroadNs;
using Road3App.Model.RoadNs;

namespace Road3App.Model
{
    public static class InitHelper
    {
        public static DispatcherTimer InitTimer(int interval, EventHandler hanlder)
        {
            DispatcherTimer timer = new DispatcherTimer();

            timer.Interval = new TimeSpan(0, 0, 0, 0, interval < 1000 ? interval : 1000);
            timer.Tick += hanlder;

            return timer;
        }
    }

    public class RoadNetwork
    {
        #region Fields

        private DispatcherTimer _timer, _timerRoads, _timerVGs, _timerCRs;
        
        #endregion

        #region Properties

        public List<CrossRoad> CRCollection { get; set; }
        public List<Road> RoadCollection { get; set; }
        public List<VehicleGenerator> VGCollection { get; set; }

        #endregion

        #region Constructors

        public RoadNetwork()
            : this(100)
        {
            
        }

        public RoadNetwork(int interval)
            : this(interval, interval, interval)
        {
            _timer = InitHelper.InitTimer(interval, (s, ea) => this.Run());
        }

        public RoadNetwork(int roadInterval, int CRInterval, int VGInterval)
        {
            CRCollection = new List<CrossRoad>();
            RoadCollection = new List<Road>();
            VGCollection = new List<VehicleGenerator>();

            //_timerRoads = InitHelper.InitTimer(roadInterval, (s, e) => RoadsCollection.ForEach(r => r.Run()));
        }

        #endregion

        #region StartStop methods

        private void Run()
        {
            this.RoadCollection.ForEach(r => r.Run());
            this.CRCollection.ForEach(cr => cr.Run());
            this.VGCollection.ForEach(vg => vg.Run());
        }

        public void Start()
        {
            //_timerRoads.Start();
            //_timerCRs.Start();
            //_timerVGs.Start();
            _timer.Start();
        }

        public void Stop()
        {
            //_timerRoads.Stop();
            //_timerCRs.Stop();
            //_timerVGs.Stop();
            _timer.Stop();
        }

        #endregion

        #region Container management methods

        public void AddRoad(Road road)
        {
            this.RoadCollection.Add(road);
            RaiseContainerAdded(road);
        }

        public void AddCrossRoad(CrossRoad cr)
        {
            this.CRCollection.Add(cr);
            RaiseContainerAdded(cr);
        }

        public void AddVehGen(VehicleGenerator vg)
        {
            this.VGCollection.Add(vg);
            RaiseContainerAdded(vg);
        }

        public void RemoveRoad(Road road)
        {
            this.RoadCollection.Remove(road);
            RaiseContainerRemoved(road);
        }

        public void RemoveCrossRoad(CrossRoad cr)
        {
            this.CRCollection.Remove(cr);
            RaiseContainerRemoved(cr);
        }

        public void RemoveVehGen(VehicleGenerator vg)
        {
            this.VGCollection.Remove(vg);
            RaiseContainerRemoved(vg);
        }

        #endregion

        #region Events

        public class ContainerEventArgs : EventArgs
        {
            public Container Container { get; private set; }

            public ContainerEventArgs(Container container)
            {
                this.Container = container;
            }
        }

        public event EventHandler<ContainerEventArgs> ContainerAdded;
        public event EventHandler<ContainerEventArgs> ContainerRemoved;
        public event EventHandler<ContainerEventArgs> ContainerChanged;

        protected void RaiseContainerAdded(Container container)
        {
            if (this.ContainerAdded != null)
                this.ContainerAdded(this, new ContainerEventArgs(container));
        }

        protected void RaiseContainerRemoved(Container container)
        {
            if (this.ContainerRemoved != null)
                this.ContainerRemoved(this, new ContainerEventArgs(container));
        }

        protected void RaiseContainerChanged(Container container)
        {
            if (this.ContainerChanged != null)
                this.ContainerChanged(this, new ContainerEventArgs(container));
        }

        #endregion
    }
}
